#pragma once
#include "XtStruct.h"
#include "util.h"
#include "SetFunc.h"
//#include "LFData"




class Spi {

public:

	int a;
	Spi * get_ptr() {
		return this;
	}

};



template  <typename T, typename N >
class BIContainer {
public:

	std::unordered_map<T, N> T2N;
	std::unordered_map<N, T> N2T;
	void insert(T t, N n) {
		T2N[t] = n;
		N2T[n] = t;
	}
	void insert(N n, T t) {
		N2T[n] = t;
		T2N[t] = n;
	}
	N& operator [](T t) {
		return T2N[t];
	}

	T& operator [](N n) {
		return N2T[n];
	}
};






template<typename T>
class OrderPolicy {
public:
	static int m_request;
	static string m_tag;
	static CAccountDetail m_acct;
	static CAccountDetail m_credit;
	static unordered_map<int, pair<int, int >> m_order_map; // requestid <------>  {order id, local id}
	static unordered_map<string, pair<int, int >> m_task_map;
	static BIContainer<char, EXtFWEntrustStatus> m_status_map;
	static void policy_init() {
		m_status_map.insert(LF_CHAR_AllTraded, XTFW_ENTRUST_STATUS_SUCCEEDED);
		m_status_map.insert(LF_CHAR_OrderInserted, XTFW_ENTRUST_STATUS_REPORTED);
		m_status_map.insert(LF_CHAR_Canceled, XTFW_ENTRUST_STATUS_CANCELED);
		m_status_map.insert(LF_CHAR_PartTradedQueueing, XTFW_ENTRUST_STATUS_PART_SUCC);
		strcpy_s(m_acct.m_strAccountKey, "2____10017____0001____49____0030057461____");
		FileAdapter::GetInstance().flush_to_file("policy.log", "[m_acct get init ]" + string(m_acct.m_strAccountKey) + "\n");

	}
	static void order_logic(int type, void* buf) {


		// api shoud check


		short msg_type = type;

		switch (msg_type) {
		case MSG_TYPE_TRADE_ENGINE_LOGIN: {

			//const char *data = reinterpret_cast<const char *>(p);
			//bufferevent_write(g_bev, data, strlen(data) + 1);
			break;
		}

		case 20: {

			LFInputOrderField* p = reinterpret_cast<LFInputOrderField*>  (buf);
			COrdinaryOrder order;
			order.m_dPrice = p->price;
			order.m_nOrderNum = p->volume;
			if (p->exchange == Exchange::EXCH_SSE) {
				strcpy_s(order.m_strExchangeID, "SH");
			}
			else {
			
				strcpy_s(order.m_strExchangeID, "SZ");
			}

			strcpy_s(order.m_strInstrumentID, p->ticker);
			//strcpy_s(order.m_strAccountKey, m_acct.m_strAccountKey);
			//strcpy_s(order.m_strAccountKey, "2____10017____0001____49____0030057461____");
			strcpy_s(order.m_strAccountKey, m_acct.m_strAccountKey);
			
			order.m_eOperationType = XTFW_OPT_BUY;
			order.m_ePriceType = XTFW_PRTP_FIX;
			strcpy_s(order.m_strRemark, "qmt test");

			string msg = "[ex]" + string(order.m_strExchangeID) + " " +
				"[px]" + to_string(order.m_dPrice) + " " +
				"[vol]" + to_string(order.m_nOrderNum) + " " +
				"[ticker]" + string(order.m_strInstrumentID) + " " +
				"[key]" + string(order.m_strAccountKey) + " " +
				"[key]" + to_string(order.m_eOperationType);



			FileAdapter::GetInstance().flush_to_file("policy.log", msg + "\n");
			m_order_map[m_request] = { p->order_id, p->local_id };

			FileAdapter::GetInstance().flush_to_file("policy.log", "request insert " + to_string(m_request)+  "  " +
																						to_string(p->order_id)+"  " +
																						to_string(p->local_id)+ "\n");
			xt_order(order , m_request++, m_tag.c_str());
			break;
		}

		case 23: {
			//(const char* accountKey, const long long nTaskId, const long long nGroupId, int nRequestId, const char* moduleTag));
			


			LFOrderActionField* p = reinterpret_cast<LFOrderActionField*>  (buf);

			m_order_map[m_request] = { p->order_id, p->local_id };

			string key = to_string(p->order_id) + to_string(p->local_id);
			long long task_id = m_task_map[key].first;
			long long group_id = m_task_map[key].second;


			string msg = "cancel order "  + string("[key]")+ key   + " [task]" + to_string(task_id) + " " +
				"[group]" + to_string(group_id);



			FileAdapter::GetInstance().flush_to_file("policy.log", msg + "\n");
			cancel_order(m_acct.m_strAccountKey, task_id, group_id, m_request++, m_tag.c_str() );
			break;

		}

		}
	}
	void set_config(const char* tag, CAccountDetail acct, CAccountDetail credit) {
		m_tag = tag;
		m_acct = acct;
		m_credit = credit;
		string msg = "[m_tag]" + string(m_tag) + " " +
					"[m_acct] " + string(m_acct.m_strAccountKey);
		FileAdapter::GetInstance().flush_to_file("policy.log", msg + "\n");
	}
};

template<typename T>
int OrderPolicy<T>::m_request = 20;


template<typename T>
string OrderPolicy<T>::m_tag = "";


template<typename T>
CAccountDetail OrderPolicy<T>::m_acct;

template<typename T>
CAccountDetail OrderPolicy<T>::m_credit;


template<typename T>
unordered_map<int, pair<int, int >> OrderPolicy<T>::m_order_map;


template<typename T>
unordered_map<string, pair<int, int >> OrderPolicy<T>::m_task_map;

template<typename T>
BIContainer<char, EXtFWEntrustStatus>  OrderPolicy<T>::m_status_map;